package com.module.ble.repo

import com.common.base.app.extras.no
import com.module.ble.db.HealthExaManager
import com.module.ble.db.SleepInfoTableQueryHelper
import com.module.ble.db.table.UserSleepInfo
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

/**
 * 作者：sosou
 * <p>
 * 版本：1.0
 * <p>
 * 创建日期：2025/3/25
 * <p>
 * 描述：仓库类，所有睡眠相关的数据操作都在此类中进行，数据库的增、删、改、查操作
 * <p>
 * 修订历史：
 */
class SleepInfoRepo private constructor() {

    private val refreshTrigger = MutableStateFlow(0)

    companion object {
        val instance by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SleepInfoRepo() }
    }

    private val dao = HealthExaManager.mSleepInfoDao

    private val scope = CoroutineScope(Dispatchers.IO)

    /**
     * 查找所有数据
     */
    fun findAll(): List<UserSleepInfo>? {
        //数据库查找所有数据
        return dao?.findAll()
    }
    /**
     * 查找所有未上传数据
     */
    fun findAllNotUp(): List<UserSleepInfo>? {
        //数据库查找所有数据
        return dao?.findAllNotUp()
    }

    /**
     * 查找所有数据
     */
    @OptIn(ExperimentalCoroutinesApi::class)
    fun findAllFlow(): Flow<List<UserSleepInfo>> = refreshTrigger.flatMapLatest { dao?.findLatestDayFlow() ?: flowOf(emptyList())}

    /**
     * 根据时间范围查询数据
     */
    fun findByTimeRange(startTime:Long, endTime:Long): List<UserSleepInfo>? {
        return dao?.findByTimeRange(startTime,endTime)
    }

    /**
     * 根据时间范围查询数据
     */
    fun findByTimeRangeByNight(startTime:Long, endTime:Long): List<UserSleepInfo>? {
        return dao?.findByTimeRangeByNight(startTime,endTime)
    }

    /**
     * 根据时间范围查询小睡数据
     */
    fun findByTimeRangeByNap(startTime:Long, endTime:Long): List<UserSleepInfo>? {
        return dao?.findByTimeRangeByNap(startTime,endTime)
    }

    /**
     * 查找所有数据
     */
    @OptIn(ExperimentalCoroutinesApi::class)
    fun findByTimeRangeFlow(startTime:Long, endTime:Long): Flow<List<UserSleepInfo>> = refreshTrigger.flatMapLatest { dao?.findByTimeRangeFlow(startTime,endTime) ?: flowOf(emptyList())}

    /**
     * 根据多个时间段查询睡眠数据
     * @param timeRanges 时间段数组，每个Pair的first为开始时间戳，second为结束时间戳
     * @return 查询到的睡眠数据列表
     */
    fun findByMultiTimeRanges(timeRanges: List<Pair<Long, Long>>): List<UserSleepInfo>? {
        if (timeRanges.isEmpty()) return emptyList()

        val query = SleepInfoTableQueryHelper.createMultiTimeRangeQuery(timeRanges)
        return dao?.findByCustomQuery(query)
    }

    /**
     * 根据多个时间段查询夜间睡眠数据
     * @param timeRanges 时间段数组，每个Pair的first为开始时间戳，second为结束时间戳
     * @return 查询到的夜间睡眠数据列表
     */
    fun findByMultiTimeRangesNight(timeRanges: List<Pair<Long, Long>>): List<UserSleepInfo>? {
        if (timeRanges.isEmpty()) return emptyList()

        val query = SleepInfoTableQueryHelper.createMultiTimeRangeNightQuery(timeRanges)
        return dao?.findByCustomQuery(query)
    }

    /**
     * 根据多个时间段查询小睡数据
     * @param timeRanges 时间段数组，每个Pair的first为开始时间戳，second为结束时间戳
     * @return 查询到的小睡数据列表
     */
    fun findByMultiTimeRangesNap(timeRanges: List<Pair<Long, Long>>): List<UserSleepInfo>? {
        if (timeRanges.isEmpty()) return emptyList()

        val query = SleepInfoTableQueryHelper.createMultiTimeRangeNapQuery(timeRanges)
        return dao?.findByCustomQuery(query)
    }

    /**
     * 根据多个时间段查询睡眠数据（Flow版本）
     * @param timeRanges 时间段数组，每个Pair的first为开始时间戳，second为结束时间戳
     * @return Flow<List<UserSleepInfo>>
     */
    @OptIn(ExperimentalCoroutinesApi::class)
    fun findByMultiTimeRangesFlow(timeRanges: List<Pair<Long, Long>>): Flow<List<UserSleepInfo>> {
        if (timeRanges.isEmpty()) return flowOf(emptyList())

        return refreshTrigger.flatMapLatest {
            val query = SleepInfoTableQueryHelper.createMultiTimeRangeQuery(timeRanges)
            dao?.findByCustomQueryFlow(query) ?: flowOf(emptyList())
        }
    }

    /**
     * 根据指定时间戳查询该时间戳当天及前6天的所有数据
     * @param timestamp 指定的时间戳（毫秒）
     * @return 7天内的睡眠数据列表
     */
    fun findByTimestampLast7Days(timestamp: Long): List<UserSleepInfo>? {
        return dao?.findByTimestampLast7Days(timestamp)
    }

    /**
     * 根据指定时间戳查询该时间戳当天及前6天的所有数据（Flow版本）
     * @param timestamp 指定的时间戳（毫秒）
     * @return Flow<List<UserSleepInfo>>
     */
    @OptIn(ExperimentalCoroutinesApi::class)
    fun findByTimestampLast7DaysFlow(timestamp: Long): Flow<List<UserSleepInfo>> {
        return refreshTrigger.flatMapLatest {
            dao?.findByTimestampLast7DaysFlow(timestamp) ?: flowOf(emptyList())
        }
    }

    /**
     * 根据指定时间戳查询该时间戳当天及前6天的夜间睡眠数据
     * @param timestamp 指定的时间戳（毫秒）
     * @return 7天内的夜间睡眠数据列表
     */
    fun findByTimestampLast7DaysNight(timestamp: Long): List<UserSleepInfo>? {
        return dao?.findByTimestampLast7DaysNight(timestamp)
    }

    /**
     * 根据指定时间戳查询该时间戳前7天的所有数据（不包含今天）
     * @param timestamp 指定的时间戳（毫秒）
     * @return 7天内的夜间睡眠数据列表
     */
    fun findByTimestampLast7DaysNotTheDayNight(timestamp: Long): List<UserSleepInfo>? {
        return dao?.findByTimestampLast7DaysNotTheDayNight(timestamp)
    }

    /**
     * 根据指定时间戳查询该时间戳当天及前6天的小睡数据
     * @param timestamp 指定的时间戳（毫秒）
     * @return 7天内的小睡数据列表
     */
    fun findByTimestampLast7DaysNap(timestamp: Long): List<UserSleepInfo>? {
        return dao?.findByTimestampLast7DaysNap(timestamp)
    }

    /**
     * 根据指定时间戳查询该时间戳当天内sleepType=1的所有数据
     * @param timestamp 指定的时间戳（毫秒）
     * @return 当天内sleepType=1的所有数据列表
     */
    fun findByTimestampSameDayWithNapSleep(timestamp: Long): List<UserSleepInfo>? {
        return dao?.findByTimestampSameDayWithNapSleep(timestamp)
    }

    /**
     * 插入数据
     */
    fun add2DB(data: UserSleepInfo?) {
        data?.let { dataIt->
            scope.launch {
                dao?.insert(dataIt)
            }
        }
    }

    suspend fun add2DBAndFetch(data: UserSleepInfo?): List<UserSleepInfo>? {
        data?.let { dataIt->
            scope.launch {
                dao?.insert(dataIt)
            }
        }
        return dao?.findAll()
    }

    /**
     * 插入数据
     */
    fun add2DB(mList: List<UserSleepInfo>) {
        mList.isEmpty().no {
            scope.launch {
                dao?.insert(mList)
            }
        }
    }

    fun insertDistinct(mList: List<UserSleepInfo>, batchSize: Int = 1500) {
        if (mList.isNullOrEmpty()) return
        scope.launch {
//        // 使用 runBlocking 确保同步执行
//        runBlocking {
            // 分批处理
            mList.chunked(batchSize).forEach { batch ->
                dao?.insert(batch) // 直接插入整个批次
            }
        }
    }

    fun updateBatch(mList: List<UserSleepInfo>, batchSize: Int = 1500) {
        if (mList.isNullOrEmpty()) return
        scope.launch {
            // 分批处理
            mList.chunked(batchSize).forEach { batch ->
                dao?.update(batch) // 分配更新
            }
        }
    }

    /**
     * 删除数据库中数据
     */
    private fun del2DB(data: UserSleepInfo?) {
        data?.let { dataIt->
            scope.launch {
                dao?.delete(dataIt)
            }
        }
    }

    /**
     * 删除数据库中所有数据
     */
     fun deleteAll() {
            scope.launch {
                dao?.deleteAll()
            }
    }

    /**
     * 自动触发 Flow 的更新，进而更新 LiveData
     */
    fun refreshData() {
        refreshTrigger.value += 1
    }

    /**
     *
     */
    fun updateAllSleepTypeToZero() {
        scope.launch {
            dao?.updateAllSleepTypeToZero()
        }
    }

    /**
     *
     */
    fun updateAllSysStatToZero() {
        scope.launch {
            dao?.updateAllSysStatToZero()
        }
    }

    /**
     *
     */
    fun updateSleepTypeToZeroForFirm1() {
        scope.launch {
            dao?.updateSleepTypeToZeroForFirm1()
        }
    }
}